﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Globalization;

namespace Chefbook.DataObjects.XmlSerialization
{
    public static class RecipeXmlSerializer
    {
        private const string Root = "Root";
        private const string Recipe = "Recipe";
        private const string Description = "Description";
        private const string Directions = "Directions";
        private const string PrepTime = "PrepTime";
        private const string CookTime = "CookTime";
        private const string Ingredients = "Ingredients";
        private const string Ingredient = "Ingredient";
        private const string Name = "Name";
        private const string Amount = "Amount";
        private const string Units = "Units";

        public static IEnumerable<Recipe> DeserializeRecipes(XDocument doc)
        {
            List<Recipe> recipes = new List<Recipe>();
            foreach (var xmlRec in doc.Root.Elements(Recipe))
            {
                recipes.Add(DeserializeRecipe(xmlRec));
            }
            return recipes;
        }

        public static XDocument SerializeRecipes(IEnumerable<Recipe> recipes)
        {
            XElement rootXml = new XElement(Root);
            foreach (var item in recipes)
            {
                rootXml.Add(SerializeRecipe(item));
            }
            XDocument xml = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"));
            xml.Add(rootXml);
            return xml;
        }

        private static XElement SerializeRecipe(Recipe recipe)
        {
            XElement recipeXml = new XElement(Recipe);
            recipeXml.Add(new XAttribute(Name, recipe.Name),
                new XElement(Description, recipe.Description),
                new XElement(Directions, recipe.Directions),
                new XElement(CookTime, recipe.CookTime.TotalMinutes),
                new XElement(PrepTime, recipe.PrepTime.TotalMinutes));
            XElement ingredientsXml = new XElement(Ingredients);
            recipeXml.Add(ingredientsXml);
            foreach (var ing in recipe.Ingredients)
            {
                ingredientsXml.Add(new XElement(Ingredient,
                    new XAttribute(Name, ing.Name),
                    new XAttribute(Amount, ing.Amount),
                    new XAttribute(Units, ing.Units)));
            }
                
            return recipeXml;
        }

        private static Recipe DeserializeRecipe(XElement recipeXml)
        {
            Recipe rec = new Recipe(null);
            rec.Description = recipeXml.Element(Description).Value;
            rec.Directions = recipeXml.Element(Directions).Value;
            rec.CookTime = TimeSpan.FromMinutes(double.Parse(recipeXml.Element(CookTime).Value, CultureInfo.InvariantCulture));
            rec.PrepTime = TimeSpan.FromMinutes(double.Parse(recipeXml.Element(PrepTime).Value, CultureInfo.InvariantCulture));
            rec.Name = recipeXml.Attribute(Name).Value;
            foreach (var ingXml in recipeXml.Element(Ingredients).Elements(Ingredient))
            {
                Ingredient i = new Ingredient(rec);
                i.Amount = float.Parse(ingXml.Attribute(Amount).Value, CultureInfo.InvariantCulture);
                i.Units = ingXml.Attribute(Units).Value;
                i.Name = ingXml.Attribute(Name).Value;
            }
            return rec;
        }
    }
}
